---
layout: post
page.title: "Creating a new repo using the Gogs API"
categories: blog
author: "te0ys"
meta: "gogs"
---

### Gogs

This week I decided to migrate my code from github to [notabug.org][notabug] for a couple of reasons. Notabug specifically exists to support free software projects and offers free private repos. Notabug runs a fork of [Gogs](https://notabug.org/hp/gogs) which is a lightweight[^1] but fully featured git service. To my knowledge the notabug fork is almost the same codebase as the upstream, but with references to non-free services removed[^2]. You can also make private repos for free here[^3], which is a great perk.

Even though I only have a few git repositories, I wanted to find a way to create new repos on Gogs without having to go to the GUI every time, so I did a little research and figured out how to use the Gogs API. It's pretty straightforward, but it still took me a while to figure out because I haven't done much work with http requests in the past.

### The API

Gogs has a RESTful API, which basically means you interact with it by submitting specific HTTP methods to specific URLS. All of the Gogs API addresses are prefixed with the path /api/v1. You can find a more or less comprehensive list of possible requests on the [wiki for the Gogs API client](https://github.com/gogs/go-gogs-client/wiki)  which is also available. I didn't want to deal with it because it's still a work in progress, but I did use the wiki to get information about various requests supported by the API.

The wiki shows that we can create a new repo with `POST /user/repos`[^3], but what does that mean?

First of all, a POST request. POST is one of several request methods provided by HTTP, basically it's a way to submit data to a website inside of the message of an HTTP request.[^4] For context, when you just pull data down from a website, you're using a GET request. If you try a get request here on these API addresses you'll get a 404 because they're set up to receive data, not serve it out. You can actually make these requests using the `curl` command, which is extremely handy.

In this case we'll be posting some JSON-formatted data which contains values for a few of the new repo's attributes. 

### The Solution

Here is the command which ultimately worked:

    curl -u "te0ys" \
    -H "content-type: application/json" \
    -X POST \
    -d '{  "name": "hello-world",
    "description": "test repo",
    "private": false}' \
    https://notabug.org/api/v1/user/repos

This looks like some serious spaghetti, so let's break it down:

- `curl -u "te0ys"` 
the `-u` flag lets you authenticate as a user and prompts for a password. Obviously you want to use your own username here.

- `-H "content-type: application/json"`
 The `-H` flag sets the header. In this case, we're telling the server that the data is formatted as JSON. Without the header, you'll get an error like this:


      curl: (6) Couldn't resolve host 'POST'
      [{"fieldNames":["Name"],"classification":"RequiredError","message":"Required"}]

- `-X POST`
 This one is pretty-much self explanatory. It sets the request type to POST. Otherwise, curl defaults to get requests.

- The `-d` or `--data` flag prefaces the data included in the POST request. This is where we submit the JSON data mentioned earler. In this case I only set the name, description, and private values, but you can also set some other things.

- The url at the end is just the full URL for the API. 

Then you run the command and it should create your repo for you, and you can go ahead and push to it!

### Migrate a Pre-existing Repo to Gogs

But what if you want to just migrate with the officially suppored api?

I was able to do it just by running this:

    curl -u "te0ys" \
    -H "content-type: application/json" \
    -X POST \
    -d '{
    "clone_addr": "https://github.com/te0ys/programming-challenges",
    "repo_name": "challenges",
    "description": "My solutions to various programming challenges",
    "uid": 12775,                                                
    "private": true}' \
    https://notabug.org/api/v1/repos/migrate

Now there are a few differences here as shown before, but it's basically the same kind of thing. Let's go through the differences just to be safe:

* `clone_addr`
This takes your old git repo address as its value.

* `repo_name` 
For some reason you have to use this instead of `name` I'm not sure why.

* `uid` 
This is the id number for your user who will own your new repo on Gogs. I'm not sure why this doesn't just get inherited from the authenticated user, but I'm sure there's a good reason. According to the wiki, you can retrieve this with  `GET /users/:username`. Get is the default request type for curl, so I just ran this:

      $curl https://notabug.org/api/v1/users/te0ys
      {"id":12775,"login":"te0ys",
      "full_name":"",
      "email":"",
      "avatar_url":"https://notabug.org/avatars/12775",
      "username":"te0ys"}%

I see here that my ID is 12775, so I just input that field as the uid. Make sure you don't put the number in quotation marks, as it's an integer.

### Conclusion

So that about wraps up this tutorial. Hopefully this helps if you're trying to get this stuff done. Just make sure to replace my values with your own. Check the [go-gogs-client wiki][https://github.com/gogs/go-gogs-client/wiki] to find out more about the numerous cool things you can do with the API.


-------------
### References:
[^1]:"A Raspberry Pi or $5 Digital Ocean Droplet is more than enough to get you started. Some even use 64MB RAM Docker CaaS." from <https://notabug.org/hp/gogs/src/master/README.md>
[^2]:<https://notabug.org/hp/gogs/issues/111>
[^3]:When I wrote this, github hadn't been giving out free private repos.
[^4]:<https://github.com/gogs/docs-api>
[^5]:<https://en.wikipedia.org/wiki/POST_(HTTP)>
[notabug]:notabug.org
[gogs]:gogs.io
